VimUnDo)H"TΝ>hze=G4غ/*} e e ehIk_~}h/70const starField = new StarField(document.body, {5_}~h/7 starCount: 200,5_~h/7 minSize: 1,5_h/7 maxSize: 3,5_h/7 speed: 5,5_h/7 color: "white" 5_h/7});5_h/7*/5_h/75_h/70function renderStarsAsWord(word, options = {}) {5_h/7 const {5_h/7# font = "bold 100px sans-serif",5_h/7 resolution = 1,5_h/73 maxStars = STAR_COUNT, // use the defined count5_h/7# transitionDuration = 5000 // ms5_h/7 } = options;5_h/75_h/82 const canvas = document.createElement("canvas");5_h/8& const ctx = canvas.getContext("2d");5_h/85_h/8 canvas.width = 1000;5_h/8 canvas.height = 300;5_h/8 ctx.fillStyle = "black";5_h/8 ctx.font = font;5_h/8 ctx.textAlign = "center";5_h/8 ctx.textBaseline = "middle";5_h/8: ctx.fillText(word, canvas.width / 2, canvas.height / 2);5_h/85_h/8M const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height).data;5_h/8 const targetPositions = [];5_h/85_h/87 for (let y = 0; y < canvas.height; y += resolution) {5_h/88 for (let x = 0; x < canvas.width; x += resolution) {5_h/8+ const i = (y * canvas.width + x) * 4;5_h/8# if (imageData[i + 3] > 128) {5_h/8` targetPositions.push([x / canvas.width * 100, y / canvas.height * 100]); // convert to %5_h/9 }5_h/9 }5_h/9 }5_h/95_h/9 // Shuffle and limit5_h/92 targetPositions.sort(() => Math.random() - 0.5);5_h/96 const selected = targetPositions.slice(0, maxStars);5_h/95_h/9B const allStars = Array.from(document.querySelectorAll(".star"));5_h/95_h/9% allStars.forEach((star, index) => {5_h/9b star.style.transition = `top ${transitionDuration}ms ease, left ${transitionDuration}ms ease`;5_h/95_h/9" if (index < selected.length) {5_h/9* const [left, top] = selected[index];5_h/9# star.style.left = `${left}%`;5_h/9! star.style.top = `${top}%`;5_h/9 star.style.opacity = 1;5_h/9 } else {5_h/9 // Fade out extras5_h/: star.style.opacity = 0;5_h/: }5_h/:5_h/: // Update position label5_h/: setTimeout(() => {5_h/:, star.position = getStarPosition(star);5_h/: }, transitionDuration);5_h/: });5_h/:}5_h/:1function renderStarsAsWord2(word, options = {}) {5_h/: const {5_h/:# font = "bold 200px sans-serif",5_h/:@ resolution = 1, // higher number = fewer stars, more spacing5_h/: maxStars = 400,5_h/; } = options;5_h/;5_h/;2 const canvas = document.createElement("canvas");5_h/;& const ctx = canvas.getContext("2d");5_h/;5_h/; canvas.width = 1000;5_h/; canvas.height = 300;5_h/; ctx.fillStyle = "black";5_h/; ctx.font = font;5_h/; ctx.textAlign = "center";5_h/; ctx.textBaseline = "middle";5_h/;: ctx.fillText(word, canvas.width / 2, canvas.height / 2);5_h/;5_h/;M const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height).data;5_h/< const starsToPlace = [];5_h/<5_h/<7 for (let y = 0; y < canvas.height; y += resolution) {5_h/<8 for (let x = 0; x < canvas.width; x += resolution) {5_h/</ const index = (y * canvas.width + x) * 4;5_h/<) const alpha = imageData[index + 3];5_h/< if (alpha > 128) {5_h/<" starsToPlace.push([x, y]);5_h/< }5_h/< }5_h/< }5_h/<5_h/<, // Sort stars randomly and trim to the max5_h/</ starsToPlace.sort(() => Math.random() - 0.5);5_h/<3 const selected = starsToPlace.slice(0, maxStars);5_h/<5_h/<" // Clear existing stars from DOM5_h/<> document.querySelectorAll(".star").forEach(s => s.remove());5_h/<3 Object.keys(stars).forEach(k => delete stars[k]);5_h/<5_h/=0 // Map canvas coordinates to percent of screen5_h/=$ const screenW = window.innerWidth;5_h/=% const screenH = window.innerHeight;5_h/=5_h/= selected.forEach(([x, y]) => {5_h/=/ const star = document.createElement("div");5_h/= star.classList.add("star");5_h/=. const percentX = (x / canvas.width) * 100;5_h/=/ const percentY = (y / canvas.height) * 100;5_h/=5_h/=% star.style.left = `${percentX}%`;5_h/=$ star.style.top = `${percentY}%`;5_h/=5_h/=' const size = Math.random() * 2 + 1;5_h/=# star.style.width = `${size}px`;5_h/=$ star.style.height = `${size}px`;5_h/=5_h/=+ const duration = Math.random() * 3 + 2;5_h/=$ const delay = Math.random() * 5;5_h/>2 star.style.animationDuration = `${duration}s`;5_h/>, star.style.animationDelay = `${delay}s`;5_h/>5_h/>* star.position = getStarPosition(star);5_h/>9 if (!stars[star.position]) stars[star.position] = [];5_h/>$ stars[star.position].push(star);5_h/>5_h/>$ document.body.appendChild(star);5_h/> });5_h/?}5_h/?,window.renderStarsAsWord = renderStarsAsWord5_h/Lstarf 5_h/Ustarfield = new Starfield();5_h/m .starFieldwindow.starField5_ h/q app.starField5_h/tapp.starField = starfield;5_ h/w,starfield = new Starfield({starCount: 200});5_  h/x0let starfield = new Starfield({starCount: 200});5_   h/z40let starField = new Starfield({starCount: 200});5_   h/Ϭ52const starField = new Starfield({starCount: 200});5_   h/5_  h/5_ h/class StarField {5_h/@ constructor({ count = 200, container = document.body } = {}) {5_h/ this.container = container;5_h/ this.starCount = count;5_h/ this.stars = [];5_h/ this.positionMap = {};5_h/l this.originalColor = getComputedStyle(document.documentElement).getPropertyValue("--star-color").trim();5_h/ this._createStars();5_h/$ window.stars = this.positionMap;5_h/ }5_h/5_h/ _getStarPosition(star) {5_h/- const left = parseFloat(star.style.left);5_h/+ const top = parseFloat(star.style.top);5_h/= if (top < 40 && left >= 40 && left <= 60) return "North";5_h/= if (top > 60 && left >= 40 && left <= 60) return "South";5_h/; if (left < 40 && top >= 40 && top <= 60) return "West";5_ h/; if (left > 60 && top >= 40 && top <= 60) return "East";5_! h/L if (top >= 40 && top <= 60 && left >= 40 && left <= 60) return "Center";5_ "!h/ return "Corner or Edge";5_!#"h/ }5_"$#h/5_#%$h/ _createStars() {5_$&%h/. for (let i = 0; i < this.starCount; i++) {5_%'&h/1 const star = document.createElement("div");5_&('h/! star.classList.add("star");5_')(h/ this._randomizeStar(star);5_(*)h/ this._placeStar(star);5_)+*h/' this.container.appendChild(star);5_*,+h/ this.stars.push(star);5_+-,h/ }5_,.-h/ }5_-/.h/5_.0/h/ _randomizeStar(star) {5_/10h/0 star.style.left = `${Math.random() * 100}%`;5_021h// star.style.top = `${Math.random() * 100}%`;5_132h/4 star.style.width = `${Math.random() * 2 + 1}px`;5_243h/5 star.style.height = `${Math.random() * 2 + 1}px`;5_354h/? star.style.animationDuration = `${Math.random() * 3 + 2}s`;5_465h/8 star.style.animationDelay = `${Math.random() * 5}s`;5_576h/% star.style.position = "absolute";5_687h/I star.style.transition = "top 1s ease, left 1s ease, opacity 1s ease";5_798h/5_8:9h/3 star.shuffle = () => this._randomizeStar(star);5_9;:h/0 star.position = this._getStarPosition(star);5_:<;h/ }5_;=<h/5_<>=h/ _placeStar(star) {5_=?>h/ const pos = star.position;5_>@?h/; if (!this.positionMap[pos]) this.positionMap[pos] = [];5_?A@h/% this.positionMap[pos].push(star);5_@BAh/ }5_ACBh/5_BDCh/ shuffleAll() {5_CEDh/ this.stars.forEach(star => {5_DFEh/ this._randomizeStar(star);5_EGFh/2 star.position = this._getStarPosition(star);5_FHGh/ });5_GIHh/ }5_HJIh/5_IKJh/) glowColor(tempColor, duration = 2500) {5_JLKh/' const lighten = (hex, percent) => {5_KMLh/5 const num = parseInt(hex.replace("#", ""), 16);5_LNMh/M const r = Math.min(255, (num >> 16) + Math.round(255 * percent / 100));5_MONh/U const g = Math.min(255, ((num >> 8) & 0xff) + Math.round(255 * percent / 100));5_NPOh/N const b = Math.min(255, (num & 0xff) + Math.round(255 * percent / 100));5_OQPh/J return `#${(1 << 24 | r << 16 | g << 8 | b).toString(16).slice(1)}`;5_PRQh/ };5_QSRh/5_RTSh/( const glow = lighten(tempColor, 10);5_SUTh/E document.documentElement.style.setProperty("--star-color", glow);5_TVUh/ setTimeout(() => {5_UWVh/U document.documentElement.style.setProperty("--star-color", this.originalColor);5_VXWh/ }, duration);5_WYXh/ }5_XZYh/5_Y[Zh/^ renderWord(word, { font = "bold 100px sans-serif", resolution = 4, duration = 1500 } = {}) {5_Z\[h/4 const canvas = document.createElement("canvas");5_[]\h/( const ctx = canvas.getContext("2d");5_\^]h/ canvas.width = 1000;5_]_^h/ canvas.height = 300;5_^`_h/ ctx.fillStyle = "black";5__a`h/ ctx.font = font;5_`bah/ ctx.textAlign = "center";5_acbh/ ctx.textBaseline = "middle";5_bdch/< ctx.fillText(word, canvas.width / 2, canvas.height / 2);5_cedh/5_dfeh/O const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height).data;5_egfh/ const targetPositions = [];5_fhgh/5_gihh/9 for (let y = 0; y < canvas.height; y += resolution) {5_hjih/: for (let x = 0; x < canvas.width; x += resolution) {5_ikjh/- const i = (y * canvas.width + x) * 4;5_jlkh/% if (imageData[i + 3] > 128) {5_kml h/ targetPositions.push([5_lnm h/% (x / canvas.width) * 100,5_mon h/& (y / canvas.height) * 100,5_npo h/ ]);5_oqph/ }5_prqh/ }5_qsrh/ }5_rtsh/5_suth/4 targetPositions.sort(() => Math.random() - 0.5);5_tvuh/= const used = targetPositions.slice(0, this.stars.length);5_uwvh/5_vxwh/% this.stars.forEach((star, i) => {5_wyxh/l star.style.transition = `top ${duration}ms ease, left ${duration}ms ease, opacity ${duration}ms ease`;5_xzyh/ if (i < used.length) {5_y{zh/$ const [left, top] = used[i];5_z|{h/% star.style.left = `${left}%`;5_{}|h/# star.style.top = `${top}%`;5_|~}h/ star.style.opacity = 1;5_}~h/ } else {5_~h/ star.style.opacity = 0;5_h/ }5_h/ });5_h/5_h/ setTimeout(() => {5_h/" this.stars.forEach(star => {5_h/4 star.position = this._getStarPosition(star);5_h/ });5_h/ }, duration);5_h/ }5_h/}5_h/5_h/ }5_h/ 5_vh//starField.renderWord("WOW", { rainbow: true });starField.explodeAndReturn();starField.startColorCycle();4setTimeout(() => starField.stopColorCycle(), 10000);starField.shuffleAll(2000);5_vh/3 starField.renderWord("WOW", { rainbow: true });5_vh/7 starField.renderWord("WOW", { rainbow: true });5_vh/3 starField.renderWord("WOW", { rainbow: true });5_vh/ 5_vh/3 starField.renderWord("WOW", { rainbow: true });5_vh/0 starField.renderWord("", { rainbow: true });5_vh/! disco(){5_vh/#6 disco(word){5_vh//7 },5_h/ setTime  starField.shuffleAll(2000);5_h/5_h/5_h/ starField.shuffleAll(2000); starField.shuffleAll(2000);5_h/ })5_h/8# starField.shuffleAll(2000);5_h/҄5_h/ґ notify(word_{5_h/Ғ5_h/Қ let starField = this5_h/ҦA4 let starField = new StarField({starCount: 200});5_h/VB5_h/5_h/5_h/5_h/5_h/5_h/5_h/5_h/5_h/5_h/5_h/5_h/5_h/5_h/5_h/5_h/class StarField {5_h/@ constructor({ count = 200, container = document.body } = {}) {5_h/ this.container = container;5_h/ this.starCount = count;5_h/ this.stars = [];5_h/ this.positionMap = {};5_h/l this.originalColor = getComputedStyle(document.documentElement).getPropertyValue("--star-color").trim();5_h/ this._createStars();5_h/$ window.stars = this.positionMap;5_h/ }5_h/5_h/ _getStarPosition(star) {5_h/- const left = parseFloat(star.style.left);5_h/+ const top = parseFloat(star.style.top);5_h/= if (top < 40 && left >= 40 && left <= 60) return "North";5_h/= if (top > 60 && left >= 40 && left <= 60) return "South";5_h/; if (left < 40 && top >= 40 && top <= 60) return "West";5_h/; if (left > 60 && top >= 40 && top <= 60) return "East";5_h/L if (top >= 40 && top <= 60 && left >= 40 && left <= 60) return "Center";5_h/ return "Corner or Edge";5_h/ }5_h/5_h/ _createStars() {5_h/. for (let i = 0; i < this.starCount; i++) {5_h/1 const star = document.createElement("div");5_h/! star.classList.add("star");5_h/ this._randomizeStar(star);5_h/ this._placeStar(star);5_h/' this.container.appendChild(star);5_h/ this.stars.push(star);5_h/ }5_h/ }5_h/5_h/ _randomizeStar(star) {5_h/0 star.style.left = `${Math.random() * 100}%`;5_h// star.style.top = `${Math.random() * 100}%`;5_h/4 star.style.width = `${Math.random() * 2 + 1}px`;5_h/5 star.style.height = `${Math.random() * 2 + 1}px`;5_h/? star.style.animationDuration = `${Math.random() * 3 + 2}s`;5_h/8 star.style.animationDelay = `${Math.random() * 5}s`;5_h/% star.style.position = "absolute";5_h/I star.style.transition = "top 1s ease, left 1s ease, opacity 1s ease";5_h/5_h/3 star.shuffle = () => this._randomizeStar(star);5_h/0 star.position = this._getStarPosition(star);5_h/ }5_h/5_h/ _placeStar(star) {5_h/ const pos = star.position;5_h/; if (!this.positionMap[pos]) this.positionMap[pos] = [];5_h/% this.positionMap[pos].push(star);5_h/ }5_h/5_h/ shuffleAll(duration = 1000) {5_h/ this.stars.forEach(star => {5_h/l star.style.transition = `top ${duration}ms ease, left ${duration}ms ease, opacity ${duration}ms ease`;5_h/7 star.style.filter = "drop-shadow(0 0 2px white)";' const left = Math.random() * 100;5_h/5_h/5_h/5_h/5_h/5_h/& const top = Math.random() * 100;5_h/# star.style.left = `${left}%`;5_ h/! star.style.top = `${top}%`;5_  h/5_   h/ setTimeout(() => {5_   h/ star.style.filter = "";5_   h/4 star.position = this._getStarPosition(star);5_  h/ }, duration);5_ h/ });5_h/ }5_h/5_h/) glowColor(tempColor, duration = 2500) {5_h/' const lighten = (hex, percent) => {5_h/5 const num = parseInt(hex.replace("#", ""), 16);5_h/M const r = Math.min(255, (num >> 16) + Math.round(255 * percent / 100));5_h/U const g = Math.min(255, ((num >> 8) & 0xff) + Math.round(255 * percent / 100));5_h/N const b = Math.min(255, (num & 0xff) + Math.round(255 * percent / 100));5_h/J return `#${(1 << 24 | r << 16 | g << 8 | b).toString(16).slice(1)}`;5_h/ };5_h/5_h/( const glow = lighten(tempColor, 10);5_h/E document.documentElement.style.setProperty("--star-color", glow);5_h/ setTimeout(() => {5_h/U document.documentElement.style.setProperty("--star-color", this.originalColor);5_h/ }, duration);5_ h/ }5_! h/5_ "!h/o renderWord(word, { font = "bold 100px sans-serif", resolution = 4, duration = 1500, rainbow = false } = {}) {5_!#"h/4 const canvas = document.createElement("canvas");5_"$#h/( const ctx = canvas.getContext("2d");5_#%$h/ canvas.width = 1000;5_$&%h/ canvas.height = 300;5_%'&h/ ctx.fillStyle = "black";5_&('h/ ctx.font = font;5_')(h/ ctx.textAlign = "center";5_(*)h/ ctx.textBaseline = "middle";5_)+*h/< ctx.fillText(word, canvas.width / 2, canvas.height / 2);5_*,+h/5_+-,h/O const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height).data;5_,.-h/ const targetPositions = [];5_-/.h/5_.0/h/9 for (let y = 0; y < canvas.height; y += resolution) {5_/10h/: for (let x = 0; x < canvas.width; x += resolution) {5_021h/- const i = (y * canvas.width + x) * 4;5_132h/% if (imageData[i + 3] > 128) {5_243 h/ targetPositions.push([5_354 h/% (x / canvas.width) * 100,5_465 h/& (y / canvas.height) * 100,5_576 h/ ]);5_687h/ }5_798h/ }5_8:9h/ }5_9;:h/5_:<;h/4 targetPositions.sort(() => Math.random() - 0.5);5_;=<h/= const used = targetPositions.slice(0, this.stars.length);5_<>=h/5_=?>h/% this.stars.forEach((star, i) => {5_>@?h/ star.style.transition = `top ${duration}ms ease, left ${duration}ms ease, opacity ${duration}ms ease, background-color 1s ease`;5_?A@h/ if (i < used.length) {5_@BAh/$ const [left, top] = used[i];5_ACBh/% star.style.left = `${left}%`;5_BDCh/# star.style.top = `${top}%`;5_CEDh/ star.style.opacity = 1;5_DFEh/ if (rainbow) {5_EGF h/. const hue = (i / used.length) * 360;5_FHG h/@ star.style.backgroundColor = `hsl(${hue}, 100%, 70%)`;5_GIHh/ }5_HJIh/ } else {5_IKJh/ star.style.opacity = 0;5_JLKh/ }5_KMLh/ });5_LNMh/5_MONh/ setTimeout(() => {5_NPOh/" this.stars.forEach(star => {5_OQPh/4 star.position = this._getStarPosition(star);5_PRQh/5 if (rainbow) star.style.backgroundColor = "";5_QSRh/ });5_RTSh/ }, duration);5_SUTh/ }5_TVUh/5_UWVh/% explodeAndReturn(duration = 1000) {5_VXWh/7 const originalPositions = this.stars.map(star => ({5_WYXh/ left: star.style.left,5_XZYh/ top: star.style.top5_Y[Zh/ }));5_Z\[h/5_[]\h/ this.stars.forEach(star => {5_\^]h/0 const angle = Math.random() * 2 * Math.PI;5_]_^h/) const radius = Math.random() * 200;5_^`_h/. const x = 50 + Math.cos(angle) * radius;5__a`h/. const y = 50 + Math.sin(angle) * radius;5_`bah/` star.style.transition = `top ${duration / 2}ms ease-out, left ${duration / 2}ms ease-out`;5_acbh/ star.style.left = `${x}%`;5_bdch/ star.style.top = `${y}%`;5_cedh/ });5_dfeh/5_egfh/ setTimeout(() => {5_fhgh/' this.stars.forEach((star, i) => {5_gihh/X star.style.transition = `top ${duration}ms ease-in, left ${duration}ms ease-in`;5_hjih/4 star.style.left = originalPositions[i].left;5_ikjh/2 star.style.top = originalPositions[i].top;5_jlkh/ });5_kmlh/ }, duration / 2);5_lnmh/ }5_monh/5_npoh/ startColorCycle() {5_oqph/ let hue = 0;5_prqh/@ if (this._colorInterval) clearInterval(this._colorInterval);5_qsrh/- this._colorInterval = setInterval(() => {5_rtsh/ hue = (hue + 2) % 360;5_suth/' this.stars.forEach((star, i) => {5_tvuh/N star.style.backgroundColor = `hsl(${(hue + i * 3) % 360}, 100%, 75%)`;5_uwvh/ });5_vxwh/ }, 100);5_wyxh/ }5_xzyh/5_y{zh/ stopColorCycle() {5_z|{h/ if (this._colorInterval) {5_{}|h/) clearInterval(this._colorInterval);5_|~}h/! this._colorInterval = null;5_}~h/B this.stars.forEach(star => star.style.backgroundColor = "");5_~h/ }5_h/ }5_h/ notify(word){5_h/ 5_h/4 let starField = new StarField({starCount: 200});5_h/2 starField.renderWord(word, { rainbow: true });5_h/! starField.explodeAndReturn();5_h/ starField.startColorCycle();5_h/8 setTimeout(() => starField.stopColorCycle(), 10000);5_h/ starField.shuffleAll(2000);5_h/ setTimeout(() => {5_h/# starField.shuffleAll(3000);5_h/ },5000)5_h/ }5_h/ disco(word){5_h/ 5_h/ let starField = this5_h/2 starField.renderWord(word, { rainbow: true });5_h/! starField.explodeAndReturn();5_h/ starField.startColorCycle();5_h/8 setTimeout(() => starField.stopColorCycle(), 10000);5_h/ starField.shuffleAll(2000);5_h/ setTimeout(() => {5_h/# starField.shuffleAll(3000);5_h/ },5000)5_h/ }5_h/}5_h/C }5_h/ 5_h/ .
5_h/g 5_h/i5_h/nclass StarField {5_h/n@ constructor({ count = 200, container = document.body } = {}) {5_h/n this.container = container;5_h/n this.starCount = count;5_h/n this.stars = [];5_h/n this.positionMap = {};5_h/nl this.originalColor = getComputedStyle(document.documentElement).getPropertyValue("--star-color").trim();5_h/n this._createStars();5_h/o$ window.stars = this.positionMap;5_h/o }5_h/o5_h/o _getStarPosition(star) {5_h/o- const left = parseFloat(star.style.left);5_h/o+ const top = parseFloat(star.style.top);5_h/o= if (top < 40 && left >= 40 && left <= 60) return "North";5_h/o= if (top > 60 && left >= 40 && left <= 60) return "South";5_h/o; if (left < 40 && top >= 40 && top <= 60) return "West";5_h/o; if (left > 60 && top >= 40 && top <= 60) return "East";5_h/oL if (top >= 40 && top <= 60 && left >= 40 && left <= 60) return "Center";5_h/o return "Corner or Edge";5_h/o }5_h/o5_h/o _createStars() {5_h/o. for (let i = 0; i < this.starCount; i++) {5_h/o1 const star = document.createElement("div");5_h/o! star.classList.add("star");5_h/o this._randomizeStar(star);5_h/p this._placeStar(star);5_h/p5_h/p( // Interaction: click to highlight5_h/p, star.addEventListener("click", () => {5_h/p: star.style.filter = "drop-shadow(0 0 5px yellow)";5_h/p, star.style.transform = "scale(1.5)";5_h/p9 console.log(`Clicked star in: ${star.position}`);5_h/p setTimeout(() => {5_ h/p! star.style.filter = "";5_ h/p$ star.style.transform = "";5_h/p }, 500);5_h/p });5_h/p5_h/p' this.container.appendChild(star);5_h/p this.stars.push(star);5_h/p }5_h/p }5_h/p5_h/p _randomizeStar(star) {5_h/q0 star.style.left = `${Math.random() * 100}%`;5_h/q/ star.style.top = `${Math.random() * 100}%`;5_h/q4 star.style.width = `${Math.random() * 2 + 1}px`;5_h/q5 star.style.height = `${Math.random() * 2 + 1}px`;5_h/q8 star.style.animationDelay = `${Math.random() * 2}s`;5_h/q% star.style.position = "absolute";5_h/qI star.style.transition = "top 1s ease, left 1s ease, opacity 1s ease";5_h/q5_h/q3 star.shuffle = () => this._randomizeStar(star);5_h/q0 star.position = this._getStarPosition(star);5_h/q }5_h/r5_h/r _placeStar(star) {5_h/r const pos = star.position;5_h/r; if (!this.positionMap[pos]) this.positionMap[pos] = [];5_h/r% this.positionMap[pos].push(star);5_h/r }5_h/r5_h/r shuffleAll(duration = 1000) {5_h/r this.stars.forEach(star => {5_h/rl star.style.transition = `top ${duration}ms ease, left ${duration}ms ease, opacity ${duration}ms ease`;5_h/r7 star.style.filter = "drop-shadow(0 0 2px white)";5_h/r 5_h/r 5_h/s 5_h/s 5_h/s 5_h/s 5_h/t' const left = Math.random() * 100;5_h/}& const top = Math.random() * 100;5_h/ہ# star.style.left = `${left}%`;5_h/ہ! star.style.top = `${top}%`;5_h/ہ5_h/ہ setTimeout(() => {5_h/ہ star.style.filter = "";5_h/ہ4 star.position = this._getStarPosition(star);5_h/ہ }, duration);5_h/ہ });5_h/ہ }5_ h/ۃ 5_ h/ۃ 5_ h/ۃ 5_ h/ۃ 5_ h/ۃ 5_ h/ۃ 5_ h/ۃ 5_ h/ۃ 5_ h/ۃ 5_ h/ۃ 5_ h/ۃ 5_ h/ۃ 5_ h/ۃ 5_ h/ۃ 5_ h/ۃ ) glowColor(tempColor, duration = 2500) {5_ h/ۄ ' const lighten = (hex, percent) => {5_ h/ۄ 5 const num = parseInt(hex.replace("#", ""), 16);5_ h/ۄ M const r = Math.min(255, (num >> 16) + Math.round(255 * percent / 100));5_ h/ۄ U const g = Math.min(255, ((num >> 8) & 0xff) + Math.round(255 * percent / 100));5_ h/ۄ N const b = Math.min(255, (num & 0xff) + Math.round(255 * percent / 100));5_  h/ۄ J return `#${(1 << 24 | r << 16 | g << 8 | b).toString(16).slice(1)}`;5_   h/ۄ  };5_    h/ۄ 5_    h/ۄ ( const glow = lighten(tempColor, 10);5_    h/ۄ E document.documentElement.style.setProperty("--star-color", glow);5_   h/ۄ  setTimeout(() => {5_  h/ۄ U document.documentElement.style.setProperty("--star-color", this.originalColor);5_ h/ۄ  }, duration);5_ h/ۄ  }5_ h/ۄ 5_ h/ۄ ^ renderWord(word, { font = "bold", resolution = 4, duration = 1500, rainbow = false } = {}) {5_ h/ۄ 4 const canvas = document.createElement("canvas");5_ h/ۄ ( const ctx = canvas.getContext("2d");5_ h/ۄ . canvas.width = this.container.clientWidth;5_ h/ۅ 4 canvas.height = this.container.clientHeight / 3;5_ h/ۅ 5_ h/ۅ 5 const fontSize = Math.floor(canvas.height / 2.5);5_ h/ۅ * ctx.font = `${fontSize}px sans-serif`;5_ h/ۅ  ctx.fillStyle = "black";5_ h/ۅ  ctx.textAlign = "center";5_ h/ۅ  ctx.textBaseline = "middle";5_ h/ۅ < ctx.fillText(word, canvas.width / 2, canvas.height / 2);5_ h/ۅ 5_  h/ۅ O const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height).data;5_!  h/ۅ  const targetPositions = [];5_ "! h/ۅ 5_!#" h/ۅ 9 for (let y = 0; y < canvas.height; y += resolution) {5_"$# h/ۅ : for (let x = 0; x < canvas.width; x += resolution) {5_#%$ h/ۅ - const i = (y * canvas.width + x) * 4;5_$&% h/ۅ % if (imageData[i + 3] > 128) {5_%'& h/ۅ  targetPositions.push([5_&(' h/ۅ % (x / canvas.width) * 100,5_')( h/ۅ & (y / canvas.height) * 100,5_(*) h/ۅ  ]);5_)+* h/ۆ  }5_*,+ h/ۆ  }5_+-, h/ۆ  }5_,.- h/ۆ 5_-/. h/ۆ 4 targetPositions.sort(() => Math.random() - 0.5);5_.0/ h/ۆ = const used = targetPositions.slice(0, this.stars.length);5_/10 h/ۆ 5_021 h/ۆ % this.stars.forEach((star, i) => {5_132 h/ۆ  star.style.transition = `top ${duration}ms ease, left ${duration}ms ease, opacity ${duration}ms ease, background-color 1s ease`;5_243 h/ۆ  if (i < used.length) {5_354 h/ۆ $ const [left, top] = used[i];5_465 h/ۆ % star.style.left = `${left}%`;5_576 h/ۆ # star.style.top = `${top}%`;5_687 h/ۆ  star.style.opacity = 1;5_798 h/ۆ  if (rainbow) {5_8:9 h/ۆ . const hue = (i / used.length) * 360;5_9;: h/ۆ @ star.style.backgroundColor = `hsl(${hue}, 100%, 70%)`;5_:<; h/ۆ  }5_;=< h/ۆ  } else {5_<>= h/ۇ  star.style.opacity = 0;5_=?> h/ۇ  }5_>@? h/ۇ  });5_?A@ h/ۇ 5_@BA h/ۇ  setTimeout(() => {5_ACB h/ۇ " this.stars.forEach(star => {5_BDC h/ۇ 4 star.position = this._getStarPosition(star);5_CED h/ۇ 5 if (rainbow) star.style.backgroundColor = "";5_DFE h/ۇ  });5_EGF h/ۇ  }, duration);5_FHG h/ۇ  }5_GIH h/ۇ 5_HJI h/ۇ % explodeAndReturn(duration = 1000) {5_IKJ h/ۇ 7 const originalPositions = this.stars.map(star => ({5_JLK h/ۇ  left: star.style.left,5_KML h/ۇ  top: star.style.top5_LNM h/ۇ  }));5_MON h/ۇ 5_NPO h/ۇ  this.stars.forEach(star => {5_OQP h/ۈ 0 const angle = Math.random() * 2 * Math.PI;5_PRQ h/ۈ ) const radius = Math.random() * 200;5_QSR h/ۈ . const x = 50 + Math.cos(angle) * radius;5_RTS h/ۈ . const y = 50 + Math.sin(angle) * radius;5_SUT h/ۈ ` star.style.transition = `top ${duration / 2}ms ease-out, left ${duration / 2}ms ease-out`;5_TVU h/ۈ  star.style.left = `${x}%`;5_UWV h/ۈ  star.style.top = `${y}%`;5_VXW h/ۈ  });5_WYX h/ۈ 5_XZY h/ۈ  setTimeout(() => {5_Y[Z h/ۈ ' this.stars.forEach((star, i) => {5_Z\[ h/ۈ X star.style.transition = `top ${duration}ms ease-in, left ${duration}ms ease-in`;5_[]\ h/ۈ 4 star.style.left = originalPositions[i].left;5_\^] h/ۈ 2 star.style.top = originalPositions[i].top;5_]_^ h/ۈ  });5_^`_ h/ۈ  }, duration / 2);5__a` h/ۈ  }5_`ba h/ۈ 5_acb h/ۈ  startColorCycle() {5_bdc h/ۉ  let hue = 0;5_ced h/ۉ @ if (this._colorInterval) clearInterval(this._colorInterval);5_dfe h/ۉ - this._colorInterval = setInterval(() => {5_egf h/ۉ  hue = (hue + 2) % 360;5_fhg h/ۉ ' this.stars.forEach((star, i) => {5_gih h/ۉ N star.style.backgroundColor = `hsl(${(hue + i * 3) % 360}, 100%, 75%)`;5_hji h/ۉ  });5_ikj h/ۉ  }, 100);5_jlk h/ۉ  }5_kml h/ۉ 5_lnm h/ۉ  stopColorCycle() {5_mon h/ۉ  if (this._colorInterval) {5_npo h/ۉ ) clearInterval(this._colorInterval);5_oqp h/ۉ ! this._colorInterval = null;5_prq h/ۉ B this.stars.forEach(star => star.style.backgroundColor = "");5_qsr h/ۉ  }5_rts h/ۉ  }5_sut h/ۉ 5_tvu h/ۉ  notify(word) {5_uwv h/ۉ - this.renderWord(word, { rainbow: true });5_vxw h/ۊ  this.explodeAndReturn();5_wyx h/ۊ  this.startColorCycle();5_xzy h/ۊ 3 setTimeout(() => this.stopColorCycle(), 10000);5_y{z h/ۊ  this.shuffleAll(2000);5_z|{ h/ۊ  setTimeout(() => {5_{}| h/ۊ  this.shuffleAll(3000);5_|~} h/ۊ  }, 5000);5_}~ h/ۊ  }5_~ h/ۊ 5_ h/ۊ  disco(word) {5_ h/ۋ - this.renderWord(word, { rainbow: true });5_ h/ۋ  this.explodeAndReturn();5_ h/ۋ  this.startColorCycle();5_ h/ۋ 3 setTimeout(() => this.stopColorCycle(), 10000);5_ h/ۋ  this.shuffleAll(2000);5_ h/ۋ  setTimeout(() => {5_ h/ۋ  this.shuffleAll(3000);5_ h/ۋ  }, 5000);5_ h/ۋ  }5_ h/ۋ 5_ h/ی -addSpecialStar({ title, content, onClick }) {5_ h/ی 6 const star = this.stars.find(s => !s._dataAttached);5_ h/ی  if (!star) return;5_ h/ی 5_ h/ی  star.classList.add("special");5_ h/ی  star._dataAttached = true;5_ h/ی 2 star._specialData = { title, content, onClick };5_ h/ی 5_ h/ی  const showPopup = (e) => {5_ h/ی  e.stopPropagation();5_ h/ی - this._showPopup(star, star._specialData);5_ h/ی , if (onClick) onClick(star._specialData);5_ h/ی  };5_ h/ی 5_ h/ی , star.addEventListener("click", showPopup);5_ h/ی / star.addEventListener("touchend", showPopup);5_ h/ی }5_ h/ی 5_ h/ی _showPopup(star, data) {5_ h/ۍ 6 const popup = document.getElementById("star-popup");5_ h/ۍ G popup.innerHTML = `

${data.title}

${data.content}
`;5_ h/ۍ  popup.style.display = "block";5_ h/ۍ 5_ h/ۍ % // Position the popup near the star5_ h/ۍ , const rect = star.getBoundingClientRect();5_ h/ۍ < popup.style.left = `${rect.left + window.scrollX + 10}px`;5_ h/ۍ : popup.style.top = `${rect.top + window.scrollY + 10}px`;5_ h/ۍ 5_ h/ۍ + // Auto-close popup when clicking outside5_ h/ۍ  const closeHandler = () => {5_ h/ۍ ! popup.style.display = "none";5_ h/ۍ 8 document.removeEventListener("click", closeHandler);5_ h/ۍ  };5_ h/ۍ J setTimeout(() => document.addEventListener("click", closeHandler), 100);5_ h/ۍ }5_ h/ۍ }5_ h/ۍD 5_ h/  5_h/ E H5_Gh/$FF_J5_6h/!58a5_6h/"5:b5_2h/$13e _showOverlay(text) {5_2h/&12 ddd _showOverlay(text) {5_2h/&12" this.overlay.innerText = text;5_2h/'12# this.overlay.style.opacity = 1;5_2h/'G12 }5_h/a _runStep(index) {5_h/3bb i5_3h/23 _runStep(index) {5_3h/23% if (index >= this.steps.length) {5_3h/23 this._clearOverlay();5_3h/23 return;5_3h/23 }5_3h/235_3h/23@ const { target, text, duration = 3000 } = this.steps[index];5_3h/23 this._clearHighlights();5_3h/23 this._showOverlay(text);5_3h/235_3h/23 if (target) {5_3h/23V const el = typeof target === 'string' ? document.querySelector(target) : target;5_3h/23 if (el) {5_3h/23+ el.classList.add("demo-highlight");5_3h/23C el.scrollIntoView({ behavior: "smooth", block: "center" });5_3h/23 }5_3h/23 }5_3h/235_3h/23 setTimeout(() => {5_3h/23 this._hideOverlay();5_3h/23 this._runStep(index + 1);5_3h/23 }, duration);5_3h/H23 }5_K-h/JLc0 text: "💬 Welcome to your Galactic Chat!",5_O;h/INPc; target: ".channels-list", // any selector from your app5_Hh/3GKc}5__h/6^`e]);5_bh/;ace demo.start();5_Z2h/JY[e^ renderWord(word, { font = "bold", resolution = 4, duration = 1500, rainbow = false } = {}) {5_Yh/_X\e5_Zh/`Yig5_ZhZvh/cKYiu&showNotify(message, duration = 3000) {/ const notify = document.createElement("div"); notify.innerText = message;# notify.className = "star-notify";$ document.body.appendChild(notify); // Animate in1 setTimeout(() => notify.style.opacity = 1, 10); // Remove after duration setTimeout(() => { notify.style.opacity = 0;, setTimeout(() => notify.remove(), 1000); }, duration);}5_Yh/Wxu }XZu5_xh/wx* showNotify(message, duration = 3000) {5_xh/wx3 const notify = document.createElement("div");5_xh/wx! notify.innerText = message;5_xh/wx' notify.className = "star-notify";5_xh/wx( document.body.appendChild(notify);5_xh/wx5_xh/wx // Animate in5_xh/wx5 setTimeout(() => notify.style.opacity = 1, 10);5_xh/wx5_xh/wx // Remove after duration5_xh/wx setTimeout(() => {5_xh/wx! notify.style.opacity = 0;5_xh/wx0 setTimeout(() => notify.remove(), 1000);5_xh/wx }, duration);5_xh/Lwx }5_ah/O`babab5_a_h/oM`c` let exists = document.querySelector(".star-notify").filter(note => note.textContent === text);abab5_ah/N`bk let exists = document.querySelector(".star-notify").filter(note => note.textContent === text).length > 0;5_aph/v`bp let exists = document.body.querySelector(".star-notify").filter(note => note.textContent === text).length > 0;5_arh/y`br let exists = document.body.querySelector(".star-notify").filter(note => note.textContent === text).length > 0;ll5_a*h/}O`bp let exists = document.body.querySelector(".star-notify").filter(note => note.textContent === text).length > 0;5_a=h/`bs let exists = document.body.querySelectorAll(".star-notify").filter(note => note.textContent === text).length > 0;5_agh/`bs let exists = document.body.querySelectorAll(".star-notify").filter(note => note.textContent === text).length > 0;5_`h/%_b }5_ah/(`f5_ah/*`b2const ponies = document.querySelectorAll('.pony');5_ah/,`b6 const ponies = document.querySelectorAll('.pony');5_dh/0ce[const countHihi = Array.from(ponies).filter(el => el.textContent.trim() === 'hihi').length;5_dh/3ceWconst count = Array.from(ponies).filter(el => el.textContent.trim() === 'hihi').length;5_dPh/8ceYconst count = Array.from(messages).filter(el => el.textContent.trim() === 'hihi').length;5_a5h/?`b8 const messages = document.querySelectorAll('.pony');5_fh/Eefs let exists = document.body.querySelectorAll(".star-notify").filter(note => note.textContent === text).length > 0;5_f h/GPeg if (exists) return;5_ ch/NQbc?// Count how many of these elements have content exactly "hihi"5_  $hHT $ window.stars = this.positionMap;5_   hHT5_  hHTDconst starSignal = (() => {5_   hHTD const starSignal = (() => {5_ hHTD this.starSignal = (() => {5_ hHTE this.trigger = starS ED }5_ !hHTE" this.trigger = starSignal;E5_  hHTE* this.trigger = starSignal.trigger;5_  hHTEA console.warn('Unknown star signal:', signalName);5_   hHTRF default:F 5_   hHUkE5_   hHUmF5_   hHUwII5_   hHUd notify('info', args);5_   hHUd this.notify('info', args);5_    hHUd this.shownotify('info', args);5_   hHUd notify('warn', args);5_   hHUd& this.showNotifynotify('warn', args);5_   hHUd notify('error', args);5_   hHUd notify('log', args);5_   %hHUd& this.showNotify(notify('log', args);5_   'hHUd( this.showNotify(notify('error', args);5_   hHUd this.showNotify('warn', args);5_    hHUd! this.showNotify('warn', args));5_   (hHUd) this.showNotify(notify('error', args));5_  &hHUd' this.showNotify(notify('log', args));5_  ! hHUd& this.showNotify(notify('log', args);5_ " !hHUd( this.showNotify(notify('error', args);5_ ! # " hHUd$ this.logEvent(notify('log', args);5_ " $ #hHUd this.showNotify('warn', args);5_ # % $hHVSd this.showNotify('info', args);5_ $ & %$hHV'T d$ window.stars = this.positionMap;5_ % ' &'hHWe( this.showLogEvent(notify('log', args);5_ & ( '(hHWe) this.showLogEvent(notify('log', args));5_ ' ) (hHWe( this.showLogEvent(notify('log', args);5_ ( * )hHWUe* this.showLogEvent(notify('error', args);5_ ) + *%hHX0Ve2 const positionMap = app.starField.positionMap;5_ * , +hHX<e this.starSignal = (() => {5_ + - ,hHXDXe this.starSignal = () => {5_ , . -hHXe }5_ - / .hHYh5_ . 0 /hHYYh showLogEvent() {5_ / 1 0hHY"h showLogEvent(..args) {5_ 0 2 1hHY$Zh this.showNotify(..args)5_ 1 3 2hHYYh5_ 2 4 3hHY]h" this.showLogEvent('info', args);5_ 3 5 4hHYch" this.showLogEvent('warn', args);5_ 4 6 5hHYfh# this.showLogEvent('error', args);5_ 5 7 6hHYi\h! this.showLogEvent('log', args);5_ 6 8 7hHYh5_ 7 9 8hHYll5_ 8 : 9hHY]unction mapLogLevel(level) {5_ 9 ; :hHY1 const { category, color } = mapLogLevel(level);5_ : < ; hHY^0 notify(level, [`[${category}]`, ...args]);5_ ; = <hHY, originalConsole.info.apply(console, args);5_ < > =hHY5_ = ? >hHY createConsoleStar('info', args);5_ > @ ? hHZ me.  me.showLogEvent('warn', args);5_ ? A @!hHZ   me.    ! me.showLogEvent('error', args);5_ @ B AhHZ_ me.   me.showLogEvent('log', args);5_ A C B hHZ`)function createConsoleStar(level, args) {5_ B D ChHZ createConsoleStar(level, args) {5_ C E DhH[* function createConsoleStar(level, args) {5_ D F EhH[+v function createConsoleStar(level, args) {5_ E G FvhH[* function createConsoleStar(level, args) {6 const { category, color } = this.mapLogLevel(level);c const message = args.map(a => (typeof a === 'object' ? JSON.stringify(a) : String(a))).join(' '); addSpecialStar({" title: category.toUpperCase(), content: message, category, color, onClick: () => {4 showNotify(level, [`[${category}]`, ...args]); }, });}5_ F H G'vhH[ &7|'(|5_ G I H' vhH[&(* function createConsoleStar(level, args) {5_ H J I1vhH[024 showNotify(level, [`[${category}]`, ...args]);5_ I K J+vhH[#*, addSpecialStar({5_ J L KvhH[1function mapLogLevel(level) { switch (level) { case 'info':4 return { category: 'Info', color: 'skyblue' }; case 'warn':6 return { category: 'Warning', color: 'orange' }; case 'error':5 return { category: 'Error', color: 'crimson' }; case 'log': default:0 return { category: 'Log', color: 'gold' }; }}5_ K M LvhH[6~ ~5_ L P M vhH[9afunction mapLogLevel(level) {5_ M ` N P164*v8hH\h029 this.showNotify(level, [`[${category}]`, ...args]);5_ P a ^ `4*v8hIni5_ ` b a<2v8hI}5_ a c b<2v8hI5_ b d c <2v8hIj }5_ c e d <2v8hI }*/5_ d e<2v8hIk/*5_ P _ Q ` ^<2v8hIY *import {WebTerminal} from "/dumb-term.js";function showTerm(options){( const term = new WebTerminal(options); term.show();}5_ ^ _<2v8hI]+import {WebTerminal} from u"/dumb-term.js";5_ P R ^ QvhH\Nc //this.showNotify(...args)5_ Q S RhI*import {WebTerminal} from "./terminal.js";5_ R T ShI)import {WebTerminal} from "/terminal.js";5_ S U ThI d.import {WebTerminal} from "/dumb-terminal.js";5_ T V UhI5_ U W VhIfunction showTerm(options){}5_ V X WhI*e( const term = new WebTerminal(options); term.open(); term.show();5_ W Y XvhIU5_ X Z YvhIo.import {WebTerminal} from "/dumb-terminal.js";function showTerm(options){( const term = new WebTerminal(options); term.show();}5_ Y [ ZvhItfunction showTerm(options){5_ Z \ [ vhIvf class StarField {5_ [ ] \) vhIg*import {WebTerminal} from "/dumb-term.js";5_ \ ]vhI65_ M O P N*44v8hH\)5*+)* this.addSpecialStar({ title: category.toUpperCase(), content: message, category, color, onClick: () => {3 const argsString = args.map(String).join(', ');: this.showNotify(level, [`[${category}]`, argsString]); },});5_ N O*55v8hH\ )+this.addSpecialStar({5_ hHT=const starSignal = (() => {2 const positionMap = app.starField.positionMap; const areaMap = { Center: 'Center', Corner: 'Corner', Edge: 'Edge', North: 'North', South: 'South', East: 'East', West: 'West',& All: Object.keys(positionMap), };? const applyEffect = (stars, effectFn, duration = 2000) => {! const active = new Set();$ stars.forEach((star, i) => {2 const { cleanup } = effectFn(star, i); active.add(cleanup); }); setTimeout(() => {- active.forEach(fn => fn && fn()); }, duration); }; const effects = {4 pulseColor: (color, size = 5) => (star) => { const orig = {2 color: star.style.backgroundColor,( width: star.style.width,* height: star.style.height,, shadow: star.style.boxShadow };/ star.style.backgroundColor = color;+ star.style.width = `${size}px`;, star.style.height = `${size}px`;@ star.style.boxShadow = `0 0 ${size * 2}px ${color}`; return { cleanup: () => {< star.style.backgroundColor = orig.color;2 star.style.width = orig.width;4 star.style.height = orig.height;7 star.style.boxShadow = orig.shadow; } }; },' flicker: (color) => (star) => { let visible = true; const orig = {2 color: star.style.backgroundColor,, shadow: star.style.boxShadow };- const flick = setInterval(() => {B star.style.backgroundColor = visible ? color : '';I star.style.boxShadow = visible ? `0 0 4px ${color}` : '';# visible = !visible; }, 200); return { cleanup: () => {) clearInterval(flick);< star.style.backgroundColor = orig.color;7 star.style.boxShadow = orig.shadow; } }; },+ shimmer: (colors) => (star, i) => {4 const orig = star.style.backgroundColor; let idx = 0;0 const interval = setInterval(() => {I star.style.backgroundColor = colors[idx % colors.length]; idx++;# }, 100 + (i % 5) * 10); return { cleanup: () => {, clearInterval(interval);6 star.style.backgroundColor = orig; } }; } };% const trigger = (signalName) => { switch (signalName) {$ // --- Notifications --- case 'notif.newDM':V applyEffect(positionMap[areaMap.Corner], effects.pulseColor('white')); break;" case 'notif.groupMsg':V applyEffect(positionMap[areaMap.Edge], effects.flicker('blue'), 1000); break;! case 'notif.mention':X applyEffect(positionMap[areaMap.Center], effects.pulseColor('magenta')); break; case 'notif.react':Z applyEffect(positionMap[areaMap.South], effects.pulseColor('gold'), 1200); break; case 'notif.typing':Y applyEffect(positionMap[areaMap.West], effects.pulseColor('teal'), 1500); break;! case 'notif.msgSent':^ applyEffect(positionMap[areaMap.East], effects.pulseColor('lightgreen'), 800); break;! case 'notif.msgRead':_ applyEffect(positionMap[areaMap.North], effects.pulseColor('lightblue'), 1000); break;" // --- User Status ---! case 'status.online':\ applyEffect(positionMap[areaMap.Center], effects.pulseColor('green'), 3000); break;" case 'status.offline':[ applyEffect(positionMap[areaMap.Center], effects.pulseColor('gray'), 3000); break; case 'status.idle':] applyEffect(positionMap[areaMap.Center], effects.pulseColor('orange'), 3000); break;! case 'status.typing':] applyEffect(positionMap[areaMap.Center], effects.flicker('lightblue'), 2000); break; case 'status.join':Y applyEffect(positionMap[areaMap.Edge], effects.pulseColor('cyan'), 1500); break; case 'status.leave':Z applyEffect(positionMap[areaMap.Edge], effects.pulseColor('black'), 1500); break; // --- System ---! case 'sys.broadcast':- areaMap.All.forEach(area => {U applyEffect(positionMap[area], effects.pulseColor('gold'), 1000); }); break; case 'sys.warning':- areaMap.All.forEach(area => {Q applyEffect(positionMap[area], effects.flicker('red'), 2000); }); break; case 'sys.down':- areaMap.All.forEach(area => {U applyEffect(positionMap[area], effects.flicker('darkred'), 3000); }); break; case 'sys.update':k applyEffect(positionMap[areaMap.North], effects.shimmer(['cyan', 'violet', 'lime']), 2500); break; case 'sys.ping':- areaMap.All.forEach(area => {U applyEffect(positionMap[area], effects.pulseColor('white'), 500); }); break;+ // --- Activity & Reactions ---" case 'activity.surge':m applyEffect(positionMap[areaMap.Center], effects.shimmer(['white', 'blue', 'purple']), 1500); break;" case 'reaction.burst':] applyEffect(positionMap[areaMap.South], effects.pulseColor('hotpink'), 1000); break; case 'reaction.lol':X applyEffect(positionMap[areaMap.South], effects.flicker('yellow'), 800); break;" case 'reaction.likes':_ applyEffect(positionMap[areaMap.Center], effects.pulseColor('deeppink'), 1000); break;' // --- Focus & Movement --- case 'focus.zone':\ applyEffect(positionMap[areaMap.Center], effects.pulseColor('white'), 1500); break; case 'focus.enter':Y applyEffect(positionMap[areaMap.West], effects.pulseColor('cyan'), 1000); break; case 'focus.exit':Y applyEffect(positionMap[areaMap.East], effects.pulseColor('gray'), 1000); break; case 'focus.idle':W applyEffect(positionMap[areaMap.North], effects.flicker('gray'), 2000); break; default:A console.warn('Unknown star signal:', signalName); } }; return { trigger };})();5_  %hHTBC) const positionMap = this.positionMap;5_  hHTLCconst signal = (() => {5_   hHTXC signal = (() => {5_   hHT`C signal () {5_   hHTuC}5_  hHTyC }5_h/ _createStars(starCount) {5_h/:  F for (let i = 0; i < starCount ? starCount : this.starCount; i++) {5_h/"3 } function showStarMessage(text, { duration = 4000,% background = "rgba(0, 0, 0, 0.75)", color = "#fff", fontSize = "1.5rem", zIndex = 9999,= position = "top-center" // or 'center', 'bottom-left', etc. } = {}) {, const msg = document.createElement("div");$ msg.classList.add("star-message"); msg.textContent = text; Object.assign(msg.style, { position: "fixed", padding: "12px 24px", borderRadius: "8px", background, color, fontSize, zIndex, opacity: "0", transform: "scale(0.95)", transition: "all 0.6s ease", pointerEvents: "none", }); // Positioning const positions = {Y "top-center": { top: "10%", left: "50%", transform: "translateX(-50%) scale(0.95)" },^ "center": { top: "50%", left: "50%", transform: "translate(-50%, -50%) scale(0.95)" },0 "bottom-left":{ bottom: "10%", left: "5%" },2 "bottom-right":{ bottom: "10%", right: "5%" }, };K Object.assign(msg.style, positions[position] || positions["top-center"]);! document.body.appendChild(msg); // Fade in requestAnimationFrame(() => { msg.style.opacity = "1";Q msg.style.transform = msg.style.transform.replace("scale(0.95)", "scale(1)"); }); // Remove after duration setTimeout(() => { msg.style.opacity = "0";P msg.style.transform = msg.style.transform.replace("scale(1)", "scale(0.9)");( setTimeout(() => msg.remove(), 600); }, duration);}5_ h/5;showStarMessage(text, {5_h/W0 "bottom-left":{ bottom: "10%", left: "5%" },5_h/X0 "bottom-left":{ bottom: "10%", left: "5%" },5_h/Y 0 "bottom-left":{ bottom: "10%", left: "5%" },5_h/^0 "bottom-left":{ bottom: "10%", left: "5%" },5_ h/a- "top-left":{ bottom: "10%", left: "5%" },5_ h/d- "top-left":{ bottom: "10%", left: "5%" },5_h/g- "top-right"{ bottom: "10%", left: "5%" },5_$h/}. "top-right"{ bottom: "10%", right: "5%" },5_h/ԁ+ "top-right"{ top: "10%", right: "5%" },5_h/Ԅ* "top-left":{ top: "10%", left: "5%" },5_h/-notify(text, {5_h/8@- "top-right": { top: "10%", right: "5%" },5_h/Թ< notify(text, {5_h/ G }%function createStarMessage(message, {! font = "bold 100px sans-serif", resolution = 4, maxStars = 300, color = "gold", duration = 5000, fadeOut = true } = {}) {2 const canvas = document.createElement("canvas");& const ctx = canvas.getContext("2d"); canvas.width = 1000; canvas.height = 300; ctx.fillStyle = "black"; ctx.font = font; ctx.textAlign = "center"; ctx.textBaseline = "middle";= ctx.fillText(message, canvas.width / 2, canvas.height / 2);M const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height).data; const positions = [];7 for (let y = 0; y < canvas.height; y += resolution) {8 for (let x = 0; x < canvas.width; x += resolution) {+ const i = (y * canvas.width + x) * 4;# if (imageData[i + 3] > 128) { positions.push([# (x / canvas.width) * 100,# (y / canvas.height) * 100 ]); } } } // Shuffle and trim, positions.sort(() => Math.random() - 0.5);, const used = positions.slice(0, maxStars); // Create stars. const newStars = used.map(([left, top]) => {/ const star = document.createElement("div");, star.classList.add("star-message-star"); Object.assign(star.style, { position: "absolute",& left: `${Math.random() * 100}%`,% top: `${Math.random() * 100}%`,, width: `${Math.random() * 2 + 1.5}px`,- height: `${Math.random() * 2 + 1.5}px`, backgroundColor: color, borderRadius: "50%", opacity: "0", transition: "all 1s ease" });$ document.body.appendChild(star);! requestAnimationFrame(() => {# star.style.left = `${left}%`;! star.style.top = `${top}%`; star.style.opacity = "1"; }); return star; }); if (fadeOut && duration > 0) { setTimeout(() => { newStars.forEach(star => {! star.style.opacity = "0";. setTimeout(() => star.remove(), 1000); }); }, duration); }}5_h/=V starMessage(message, {5_.h/z?-/V- "top-right": { top: "10%", right: "5%" },5_h/ _createStars(extra = 0) {5_h//starField.renderWord("WOW", { rainbow: true });starField.explodeAndReturn();starField.startColorCycle();4setTimeout(() => starField.stopColorCycle(), 10000);starField.shuffleAll(2000);5